package com.tp2.dao;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

import com.tp2.dominio.CuponDescuento;

public class ParserCupones extends Parser {

	private Collection<CuponDescuento> cupones;
	private CuponDescuento cuponTmp;
	private int cantidadCupones;

	public ParserCupones() {
		super("cuponesValidos.xml");
		this.nombreXML = "src/main/resources/cuponesValidos.xml";
		cupones = new ArrayList<CuponDescuento>();
		parsear();
		
	}

	public ParserCupones(String nombreXML) {
		super(nombreXML);
		cupones = new ArrayList<CuponDescuento>();
		parsear();
	}
	
	public void parsear(){
		cupones.clear();
		parseDocument();
	}

	public Collection<CuponDescuento> getCupones() {
		return cupones;
	}

	public void setCupones(Collection<CuponDescuento> cupones) {
		this.cupones = cupones;
	}

	@Override
	public void startElement(String s, String s1, String elementName,
			Attributes attributes) throws SAXException {

		if (elementName.equalsIgnoreCase("cupones")) {
			this.cantidadCupones = Integer.parseInt(attributes
					.getValue("contador"));

		}

		if (elementName.equalsIgnoreCase("Cupon")) {
			int codigo = Integer.parseInt(attributes.getValue("codigo"));
			String descripcion = attributes.getValue("descripcion");
			double topeDevolucion = Double.parseDouble(attributes
					.getValue("tope"));
			double importe = Double.parseDouble(attributes.getValue("importe"));
			cuponTmp = new CuponDescuento(importe, topeDevolucion,descripcion);
			cuponTmp.setCodigo(codigo);
		}

	}

	@Override
	public void endElement(String s, String s1, String element)
			throws SAXException {

		if (element.equalsIgnoreCase("Cupon")) {
			cupones.add(cuponTmp);
		}

	}

	private Document abrirXML() {

		try {
			DocumentBuilderFactory docFactory = DocumentBuilderFactory
					.newInstance();
			DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
			Document doc = docBuilder.parse(this.nombreXML);

			return doc;

		} catch (Exception e) {

			System.out.println("Fallo al abrir el xml");
			return null;
		}

	}

	private void cerrarXML(Document doc) {

		try {
			TransformerFactory transformerFactory = TransformerFactory.newInstance();
			Transformer transformer = transformerFactory.newTransformer();
			DOMSource source = new DOMSource(doc);
			StreamResult result = new StreamResult(new File(this.nombreXML));
			transformer.setOutputProperty(OutputKeys.INDENT, "yes");
			transformer.transform(source, result);

		} catch (Exception e) {

			System.out.println("Fallo al cerrar el xml");
		}
		
		parsear();

	}

	public void borrarCupon(int codigo){
		
		Document doc = abrirXML();

		Node cupones = doc.getFirstChild();

		NodeList list = cupones.getChildNodes();

		for (int i = 0; i < list.getLength(); i++) {

			Node cupon = list.item(i);
			if (cupon.getNodeName().equalsIgnoreCase("cupon")) {

				if (Integer.parseInt(cupon.getAttributes().getNamedItem("codigo").getNodeValue()) == codigo) {
					cupones.removeChild(cupon);
					break;
				}
			}

		}
		
		cerrarXML(doc);
		
	}

	public void agregarCupon(CuponDescuento cupon) {

		Document doc = abrirXML();
		Node cupones = doc.getFirstChild();

		Element nuevoCupon = doc.createElement("cupon");
		cupon.setCodigo(getCodigoNuevoCupon(cupones));
		nuevoCupon.setAttribute("codigo", Integer.toString(cupon.getCodigo()));
		nuevoCupon.setAttribute("tope", Double.toString(cupon.getTope()));
		nuevoCupon.setAttribute("importe", Double.toString(cupon.getImporte()));
		nuevoCupon.setAttribute("descripcion", cupon.getDescripcion());

		cupones.appendChild(nuevoCupon);
		
		cerrarXML(doc);

	}

	public static void main(String[] args) {

		ParserCupones parser = new ParserCupones("cuponesValidosTest.xml");

		for(CuponDescuento cupon: parser.getCupones()){
			
			System.out.println(cupon.getCodigo());
			
		}
		
		parser.borrarCupon(9);
		
		for(CuponDescuento cupon: parser.getCupones()){
			
			System.out.println(cupon.getCodigo());
			
		}
		System.out.println("jaja" + parser.getCantidadCupones());

	
		CuponDescuento cupon = new CuponDescuento(13.4, 20, "NUEVO CUPON");
		parser.agregarCupon(cupon);
		
		for(CuponDescuento cupon2: parser.getCupones()){
			
			System.out.println(cupon2.getCodigo());
			
		}
		
		System.out.println("jaja" + parser.getCantidadCupones());
	}

	public int getCantidadCupones() {
		return cantidadCupones;
	}

	public void setCantidadCupones(int cantidadCupones) {
		this.cantidadCupones = cantidadCupones;
		
	}
	
	private int getCodigoNuevoCupon(Node cupones){
		
		int nuevoCodigo = getCantidadCupones() + 1;
		this.setCantidadCupones(nuevoCodigo);
		cupones.getAttributes().getNamedItem("contador").setNodeValue(Integer.toString(nuevoCodigo));
		
		return nuevoCodigo;
		
	}

	public CuponDescuento buscarCupon(String codigoCupon) throws Exception{

		parsear();
		
		for (CuponDescuento cupon : cupones) {

			if (cupon.getCodigo() == Integer.parseInt(codigoCupon))
				return cupon;
		}

		throw new Exception("Cupon no encontrado");
	}

}
